package com.yuzhihao.writejvm.intfec;

import com.yuzhihao.writejvm.clazz.ClassInfo;
import com.yuzhihao.writejvm.constant.ConstantClassInfo;
import com.yuzhihao.writejvm.format.ClassFormatEnum;
import com.yuzhihao.writejvm.format.PrintFormat;
import com.yuzhihao.writejvm.read.Parse;
import lombok.Data;
import lombok.extern.log4j.Log4j2;
import org.springframework.util.CollectionUtils;

import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * interfaces_count interfaces[]
 * Each value in the interfaces array must be a valid index into the constant_pool table. The constant_pool entry at each value of interfaces[i], where 0 ≤ i < interfaces_count, must be a CONSTANT_Class_info structure representing an interface that is a direct superinterface of this class or interface type, in the left-to-right order given in the source for the type.
 *
 * @author yzh
 * @since 2021年12月09日14:30:25
 */
@Data
@Log4j2
public class InterfaceInfo implements Parse {

    private ClassFormatEnum cfe_is = ClassFormatEnum.interfaces_count;

    private ClassFormatEnum cfe_i = ClassFormatEnum.interfaces;

    private int count;

    private List<Integer> indexs = new ArrayList<>();

    private List<String> values = new ArrayList<>();

    @Override
    public void parse(DataInputStream dis, ClassInfo ci) {
        try {
            this.count = Parse.byteToInt(cfe_is.getB(), dis);
            this.index(dis);
        } catch (IOException e) {
            log.error(e);
        }

        this.out(ci);
    }

    public void out(ClassInfo ci) {
        if(!CollectionUtils.isEmpty(this.indexs)){
            for (Integer index : indexs) {
                ConstantClassInfo cp = (ConstantClassInfo)ci.getCp_info().getPools().get(String.valueOf(index));
                values.add(cp.getConstant());
            }
            StringBuilder intfac = new StringBuilder(PrintFormat.EMPTY+"implements"+PrintFormat.EMPTY);
            for (String value : values) {
                intfac.append(value).append(",");
            }
            intfac.delete(intfac.length()-1,intfac.length());
            ci.getThis_class().setIntfac(intfac.toString());
        }

        ci.setInterfaces_count(this.count);
        ci.setInterfaces(this);
    }

    public void index(DataInputStream dis) throws IOException {
        int i = 0;
        while (i < this.count){
            int index = Parse.byteToInt(cfe_is.getB(), dis);
            indexs.add(index);
            i++;
        }
    }

}
